#define _SVID_SOURCE 1        /* Requerido por algunos gcc */
#include <stdio.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/shm.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#define DIRECTORIO "/tmp"
#define TRUE	1
#define FALSE	0

/*
 * Claves para las Colas, los Semaforos y las Shared Memory
 */

/* Definimos 2 tipos de Colas: externa e interna. */
#define COLA_INTERNA	1
#define COLA_EXTERNA	2

/* Definimos los ID's de los mensajes que intercambiamos entre los procesos */
#define MSG_ARMADO_PROD		1
#define MSG_ARMADO_PROC		2
#define MSG_ARMADO_CAJA		21
#define MSG_ARMADO_PUERTA	22
#define MSG_ARMADO_CABINA	23
#define MSG_PUERTA_PROD		3
#define MSG_PUERTA_PROC		4
#define MSG_CABINA_PROD		5
#define MSG_CABINA_PROC		6
#define MSG_CABINA_FLOOR	61
#define MSG_CABINA_SPIDER	62
#define MSG_CABINA_FRAME	63
#define MSG_CAJA_PROD		7
#define MSG_CAJA_PROC		8
#define MSG_FLOOR_PROD		9
#define MSG_FLOOR_PROC		10
#define MSG_SPIDER_PROD		11
#define MSG_SPIDER_PROC		12
#define MSG_FRAME_PROD		13
#define MSG_FRAME_PROC		14
#define MSG_PAINTSHOP		15
#define MSG_OCOMPRAS		16
#define MSG_PROVEEDOR		17

/*
 * Estructuras y definicion de tipos de mensajes
 */

typedef struct
{
    int codParte;
    int cantidad;
} t_parte;

/*
 * Piezas y materias primas de Proveedores Externos
 */
typedef struct {
    int codPieza;
    int cantNecesaria;
} t_pieza;

/*
 * Tabla de procesos de un sector de produccion
 */
typedef struct {
    int codProceso;				 /* Equipo/Proceso que hace el trabajo */
    int tiempoProceso;
    char obrero[25];
    t_parte tablaPartes[10];
    t_pieza tablaPiezas[25];
    t_parte parteProducida;
} t_proceso;

/* 
 * Kanban de Produccion
 * Descipcion: Establece la cantidad de vehiculos a producir.
 */
typedef struct {
    long mtype;					/* Sector al que va dirigido el mensaje */
    long ventas;				/* ID de Oficina de Ventas que lo emitio */
    long sector;
    int nroInicial;
    int cantVehiculos;
    t_proceso tablaProcesos[10];
    long sectorSiguiente;
    int cantidad;
} m_kanbanproduccion;

/*
 * Kanban entre procesos
 * Descipcion: El sector anterior nos dice su disponibilidad para recibir partes.
 */
typedef struct {
    long mtype;					/* Sector al que va dirigido el mensaje */
    long nroSector;				/* Sector que emite el Kanban entre procesos */
    int nroVehiculo;
    int codParte;
    int nroOrden;				/* Si se requiere mas de una parte por vez */
} m_kanbanentreprocesos;

/*
 * Estructura con los datos del Proveedor
 */
typedef struct {
    long proveedor;
    char razonSocial[50];
    char domicilio[150];
    char fecha[8];
    char tiempoEntrega[4];			/* En horas */
    int nroOrdenCompra;			 	/* Incrementar para cada Kanban Proveedor */
    int codPieza;
    char descripcion[25];
} t_proveedor;

/*
 * Kanban Proveedor para Proveedor
 */
typedef struct {
    long mtype;					/* El ID del Proveedor que lo procesa */	
    //t_proveedor datosProveedor;
    long sector;				/* Sector al que se devuelve el mensaje */
    int cantidad;
    int tugger;					/* Completa compras */
    int darsena;				/* Completa compras */
    int cantidadEntregada;
    int fechaEntrega;				/* completa el proceso que recibe */
    int horaEntrega;				/* completa el proceso que recibe */
    int entregada;				/* Los posibles estados son: */
} m_kanbanproveedor;				/* 0=entregada
						 * 1=en proceso de entrega
						 * 2=pagada (para compras)
						 */
/*
 * Kanban Proveedor para Compras
 */
typedef struct {
    long mtype;					/* El ID de la Oficina de Compras que la procesa */
    //t_proveedor datosProveedor;
    long sector;				/* Sector al que se devuelve el mensaje */
    int cantidad;
    int tugger;					/* Completa compras */
    int darsena;				/* Completa compras */
    int cantidadEntregada;
    int fechaEntrega;				/* completa el proceso que recibe */
    int horaEntrega;				/* completa el proceso que recibe */
    int entregada;				/* Los posibles estados son: */
} m_kanbancompras;				/* 0=entregada
						 * 1=en proceso de entrega
						 * 2=pagada (para compras)
						 */

/* 
 * Estructuras para memoria compartida entre los procesos de un mismo sector
 */

/*
 * Tabla Proveedores que envia la oficina de Compras cada cierta cantidad de tiempo
 */
typedef struct{
    long sector;
    t_proveedor tablaProveedores[20];
} m_proveedores;

/*
 * Stock de una pieza/materia prima
 */
typedef struct{
    int pieza;					/* Tipo de pieza */
    int stock;					/* Cantidad maxima de stock que puedo tener (tamanio de la cola) */
    int stockMinimo;				/* Cantidad minima de stock que necesito para trabajar */ 
    int stockLibre;				/* Cantidad de stock que me falta para completar */
    int estado;					/* 0 sin Kanban Proveedor, 1 con Kanban Proveedor */
} t_stock;
